﻿using Smile.Converter;
using Smile.Network.Http;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
#if NETFX_CORE
using Windows.Storage.Streams;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
#endif

namespace Smile.Network.OAuth
{
    public class TwitterClient : OAuthClientBase
    {
        // @Public
        public TwitterClient()
            : base(
                    "https://api.twitter.com/oauth/request_token",
                    "https://api.twitter.com/oauth/authorize",
                    "http://api.twitter.com/oauth/access_token")
        {
        }


        // @Protected
        protected override string GenerateBaseString(string targetUrl, UriArgumentsDictionary parameters, string method = "POST")
        {
            return method 
                + "&"
                + Uri.EscapeDataString(targetUrl)
                + "&"
                + Uri.EscapeDataString(parameters.ToUriArgumentsString());
        }

        protected override string GenerateSignature(string baseString = "")
        {
            var signInKey = string.Format(
                "{0}&{1}",
                ConsumerSecret,
                TokenSecret);

            // Econcoding signature.
            IBuffer keyMaterial = CryptographicBuffer.ConvertStringToBinary(signInKey, BinaryStringEncoding.Utf8);
            var hmacSha1Provider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
            CryptographicKey macKey = hmacSha1Provider.CreateKey(keyMaterial);
            IBuffer dataToBeSigned = CryptographicBuffer.ConvertStringToBinary(baseString, BinaryStringEncoding.Utf8);
            IBuffer signatureBuffer = CryptographicEngine.Sign(macKey, dataToBeSigned);
            String signature = CryptographicBuffer.EncodeToBase64String(signatureBuffer);
            
            return signature; 
        }

        protected override UriArgumentsDictionary GenerateRequestTokenParameters()
        {
            string timestamp = DateTimeConverter
                .ToUnixTimeStamp(DateTime.Now)
                .ToString();

            // Filling needed parameters
            var parameters = new UriArgumentsDictionary()
            {
                {"oauth_consumer_key", ConsumerKey},
                {"oauth_nonce", GenerateNonce()},
                {"oauth_signature_method", "HMAC-SHA1"},
                {"oauth_timestamp", timestamp},
                {"oauth_version", "1.0"}
            };
            string baseString = GenerateBaseString(RequestTokenUrl, parameters);
            parameters.Add("oauth_signature", GenerateSignature(baseString));

            return parameters;
        }

        protected override UriArgumentsDictionary GenerateAccessTokenParameters()
        {
            string timestamp = DateTimeConverter
                .ToUnixTimeStamp(DateTime.Now)
                .ToString();

            //  Filling needed parameters
            var parameters = new UriArgumentsDictionary()
            {
                {"oauth_consumer_key", ConsumerKey},
                {"oauth_nonce", GenerateNonce()},
                {"oauth_signature_method", "HMAC-SHA1"},
                {"oauth_timestamp", timestamp},
                {"oauth_token", Token},
                {"oauth_version", "1.0"},
                {"oauth_verifier", Verifier}
            };
            string baseString = GenerateBaseString(AccessTokenUrl, parameters);
            parameters.Add("oauth_signature", GenerateSignature(baseString));

            return parameters;
        }
    }
}
